package com.quark.common.exception;

import com.quark.result.RequestResult;
import com.quark.result.ResultCode;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;


/**
 * @author 张高昌
 * @date 2021/10/31 18:37
 * @description 全局异常处理
 */
@RestController
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 项目运行中出现的异常进行处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public RequestResult handle(Exception e) {
        e.printStackTrace();
        return RequestResult.success(ResultCode.SYSTEM.getCode(), ResultCode.SYSTEM.getMessage());
    }

    /**
     * get,post请求方式错误
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(ServletException.class)
    public RequestResult handleHttpRequestMethod(ServletException e) {

        e.printStackTrace();
        return RequestResult.success(ResultCode.HTTP_REQUEST_METHOD.getCode(), ResultCode.HTTP_REQUEST_METHOD.getMessage());
    }

    /**
     * 对使用断言的异常进行处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(CustomException.class)
    public RequestResult handle(CustomException e) {
        if (e.getErrorCode() != null) {
            return RequestResult.success(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMessage());
        }

        return RequestResult.success(ResultCode.FAILED.getCode(), e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public RequestResult handleValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();

        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                String message = fieldError.getField() + fieldError.getDefaultMessage();
                return RequestResult.validateFailed(message);
            }
        }

        return RequestResult.validateFailed(null);
    }

    /**
     * 对控制层传递过来的参数验证
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(BindException.class)
    public RequestResult handleValidException(BindException e) {
        if (e.getBindingResult().hasErrors()) {
            FieldError fieldError = e.getBindingResult().getFieldError();
            if (fieldError != null) {
                String message = fieldError.getField() + fieldError.getDefaultMessage();
                return RequestResult.success(ResultCode.VALIDATE_FAILED.getCode(), message);
            }
        }

        return RequestResult.success(ResultCode.VALIDATE_FAILED.getCode(), ResultCode.VALIDATE_FAILED.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(AccessDeniedException.class)
    public RequestResult handle(AccessDeniedException e) {
        if (e.getMessage() != null) {
            return RequestResult.success(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage());
        }

        return RequestResult.success(ResultCode.FORBIDDEN.getCode(), e.getMessage());
    }

}
